package com.dhcc.dao.impl;

import com.dhcc.dao.BaseDao;
import com.dhcc.utils.PageControl;
import com.dhcc.utils.Pager;

import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.List;
@Transactional
public class BaseDaoImpl<T> implements BaseDao<T> {
	//clazz中存储了当前操作的类型，即泛型T
	protected Class<T> clazz;

	@PersistenceContext
	protected EntityManager entityManager;

	public BaseDaoImpl() {
		ParameterizedType type = (ParameterizedType) this.getClass()
				.getGenericSuperclass();
		clazz = (Class<T>) type.getActualTypeArguments()[0];
	}

	@Override
	public void save(T t) {

		entityManager.persist(t);
	}

	/**
	 * 
	 * @param t
	 */
	@Override
	public void update(T t) {

		Method method = null;
		try {
			method = clazz.getDeclaredMethod("getId");

			//通过ID查询T对象
			T existT = (T) entityManager.find(clazz, method.invoke(t));
			//若查询查询成功则
			if (existT != null) {
				//merge()会创建一个对象的副本，然后对这个副本进行插入操作
				entityManager.merge(t);
			}
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

	}

	@Override
	public void delete(T t) {

		Method method = null;

		try {
			method = clazz.getDeclaredMethod("getId");

			T exitT = (T) entityManager.find(clazz, method.invoke(t));

			if (exitT != null) {

				entityManager.remove(exitT);
			}

		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

	}

	@Override
	public T get(Long id) {
		return (T) entityManager.find(clazz, id);
	}

	@Override
	public List<T> query() {

		String jpql = "FROM " + clazz.getSimpleName();

		return entityManager.createQuery(jpql).getResultList();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pager<T> query(PageControl pc) {

		Pager<T> pager = new Pager<T>();
		String jpql = "FROM " + clazz.getSimpleName();

		String jpql2 = "SELECT count(*) FROM " + clazz.getSimpleName();

		Long count = (Long) entityManager.createQuery(jpql2).getSingleResult();
		pc.setSumCount(count);
		
		int start = (pc.getCurrentIndex()-1) * pc.getPagesize();
	

		List<T> list =  entityManager.createQuery(jpql)
				.setFirstResult(start)
				.setMaxResults(pc.getPagesize()).getResultList();
		pager.setList(list);
		//页码控制设置
		pc = detailPage(pc);
		
		pager.setPageControl(pc);
		
		
		return pager;
	}
	/**
	 * 处理分页参数
	 * @param pc
	 * @return
	 */
	protected PageControl detailPage(PageControl pc) {
		
		long sumPage = pc.getSumCount()/pc.getPagesize();
		if (pc.getSumCount()%pc.getPagesize()>0) {
			
			sumPage++;
		}
		pc.setSumPage(sumPage);
		
		long everyPageShowPageNum = pc.getEveryPageShowPageNum();//分页一次显示多少页
		long minpage = 0 ;//当前显示最大页码
		long maxpage = 0 ;
		long index = pc.getCurrentIndex();
		
		//当总数不足以达到一下页时
		if (sumPage <= everyPageShowPageNum) {
			
			maxpage = sumPage;
			minpage = 1;
		}else {
			
			long buff = everyPageShowPageNum/2;//取中间数。maxpage=index+buff
			buff = index + buff; //当前页加每页显示的页码
			if (buff <=everyPageShowPageNum) {  //可以有下一页，但在第一页且没有达到页码不间值
				maxpage = everyPageShowPageNum;
				minpage = 1;
			}else if (buff< sumPage) { // 中间页预算小于最大页码数时
				maxpage = buff;
				minpage = maxpage - everyPageShowPageNum + 1;
			}else if (buff >= sumPage) {
				maxpage = sumPage;
				minpage = maxpage - everyPageShowPageNum + 1;
			}
		}
		pc.setMaxPage(maxpage);
		pc.setMinPage(minpage);
		return pc;
	}

	/* (non-Javadoc)
	 * @see com.dhcc.dao.BaseDao#datchDelete(java.lang.String)
	 */
	@Override
	public int datchDelete(String ids) {

		String[] tempids = ids.split(",");
		int num = 0;
		for (String id : tempids) {
			long temp = Long.parseLong(id);
			try {
				entityManager.remove(entityManager.find(clazz, temp));
			} catch (Exception e) {
				num = 0;
				e.printStackTrace();
			}
		}
		num = 1;
		return num;
	}

}
